package com.blackshadowgame.rps.client;

import com.blackshadowgame.rps.GameCode;
import com.blackshadowgame.rps.GameResultData;
import com.blackshadowgame.rps.GameServiceInterfaceStub;
import com.blackshadowgame.rps.IGameServiceInterface;
import com.blackshadowgame.rps.slice.BaseSlice;
import com.blackshadowgame.utils.AppConsts;
import com.blackshadowgame.utils.DeviceUtils;
import com.blackshadowgame.utils.LogUtil;
import ohos.aafwk.ability.IAbilityConnection;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.bundle.ElementName;
import ohos.distributedschedule.interwork.DeviceInfo;
import ohos.rpc.IRemoteObject;
import ohos.rpc.RemoteException;

import java.util.List;
import java.util.Random;

public class GameClient implements IGameServiceInterface{
    private static final String TAG = GameClient.class.getSimpleName();

    private IGameServiceInterface gameService = null;
    private Random random = null;
    private int playerId = -1;
    private String serviceName = "";

    private static GameClient _inst = null;
    public static GameClient getInstance(){
        if(_inst == null){
            _inst = new GameClient();
        }

        return _inst;
    }

    private GameClient(){

    }

    public void init(){

    }

    public String getServiceName(){
        return serviceName;
    }

    private void addLog(String log){
        BaseSlice.addLog(TAG, log);
    }

    // 创建连接回调实例
    private IAbilityConnection connection = new IAbilityConnection() {
        // 连接到 Service 的回调
        @Override
        public void onAbilityConnectDone(ElementName elementName, IRemoteObject
                iRemoteObject, int resultCode) {

            addLog("连接成功！");
            gameService = GameServiceInterfaceStub.asInterface(iRemoteObject);
            random = new Random();

            testConnection();
        }

        // 断开与连接的回调
        @Override
        public void onAbilityDisconnectDone(ElementName elementName, int resultCode) {
//            LogUtil.info(TAG,"===> onAbilityDisconnectDone");
            addLog("连接断开！");
            gameService = null;
            random = null;
            serviceName = "";
        }
    };

    public List<DeviceInfo> queryDevices() {
//        addInfo("开始查询在线设备...");
        return DeviceUtils.getAllDevices();
    }

    public boolean isConnected(){
        return gameService != null;
    }

    public boolean startLocalGameService(){
        String deviceId = "";
        String bundleName = AppConsts.BundleName;
        String abilityName = AppConsts.GameHostAbility;

        Intent intent = new Intent();
        Operation operation = new Intent.OperationBuilder()
                .withDeviceId(deviceId)
                .withBundleName(bundleName)
                .withAbilityName(abilityName)
//                .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
                .build();
        intent.setOperation(operation);

        addLog("准备启动本地游戏服务...");
        try{
            BaseSlice.getActiveSlice().startAbility(intent);
            return true;
        }catch (Exception e){
            LogUtil.error(TAG, "Exception: " + e.getLocalizedMessage());
            e.printStackTrace();
            return false;
        }
    }

    public void connectLocalGameService(){
        connectGameService(null);
    }

    public void connectGameService(DeviceInfo device){
        serviceName = (device==null?"本机":device.getDeviceName());
        addLog("准备连接游戏服务...目标设备：" + serviceName);

        String deviceId = device==null?"":device.getDeviceId();
        String bundleName = AppConsts.BundleName;
        String abilityName = AppConsts.GameHostAbility;

        Intent intent = new Intent();
        Intent.OperationBuilder builder = new Intent.OperationBuilder();
        builder.withDeviceId(deviceId)
                .withBundleName(bundleName)
                .withAbilityName(abilityName);
        if(device!=null){
            builder.withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE);
        }
        Operation operation = builder.build();

        intent.setOperation(operation);
        BaseSlice.getActiveSlice().connectAbility(intent, connection);
        addLog("发送连接请求，等待连接...");
    }

    public boolean testConnection(){
        if(gameService == null){
            return false;
        }

        boolean valid = false;
        try{
            int a = random.nextInt(100);

            addLog("测试连接，发送测试数字：" + a);
            int b = gameService.echo(a);
            addLog("接收到数字：" + b);

            valid = (a==b);
        }catch (RemoteException e){
            addLog("测试失败：" + e.getLocalizedMessage());
            e.printStackTrace();
            return false;
        }

        return valid;
    }

    public void disconnect(){
        if(gameService == null){
            return;
        }
        gameService = null;

        addLog("尝试断开连接");
        BaseSlice.getActiveSlice().disconnectAbility(connection);
    }

    public IGameServiceInterface getGameService(){
        return gameService;
    }

    public int getPlayerId(){
        return playerId;
    }

    @Override
    public int echo(int a) throws RemoteException {
        if(gameService == null){
            return a - 1;
        }

        return  gameService.echo(a);
    }

    @Override
    public int sendInput(int pid, int inputCode) throws RemoteException {
        if(gameService == null){
            return GameCode.ERROR;
        }
        return gameService.sendInput(pid, inputCode);
    }

    public int sendInput(int inputCode){
        int errorCode = GameCode.ERROR;
        try{
            errorCode = sendInput(playerId, inputCode);
            addLog("发送指令：" + errorCode);
        }catch (RemoteException e){
            addLog("发送指令失败：" + e.getLocalizedMessage());
            e.printStackTrace();
        }

        return errorCode;
    }

    @Override
    public GameResultData queryGameResult(int pid) throws RemoteException {
        if(gameService == null){
            return null;
        }

        return gameService.queryGameResult(pid);
    }

    public GameResultData queryGameResult(){
        try{
            GameResultData result = queryGameResult(playerId);
            addLog("查询游戏结果：" + result.state);
            return result;
        }catch (RemoteException e){
            addLog("查询游戏结果失败：" + e.getLocalizedMessage());
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public int leaveGame(int pid) throws RemoteException {
        if(gameService == null){
            return GameCode.ERROR;
        }

        return gameService.leaveGame(pid);
    }

    @Override
    public int nextGame(int pid) throws RemoteException {
        if(gameService == null){
            return GameCode.ERROR;
        }

        return gameService.nextGame(playerId);
    }

    public int nextGame(){
        int errorCode = GameCode.ERROR;
        try{
            errorCode = nextGame(playerId);
            addLog("开始下一局：" + errorCode);
        }catch (RemoteException e){
            addLog("开始下一局失败：" + e.getLocalizedMessage());
            e.printStackTrace();
        }

        return errorCode;
    }

    public int leaveGame(){
        int errorCode = GameCode.ERROR;
        try{
            errorCode = leaveGame(playerId);
            addLog("离开游戏：" + errorCode);
        }catch (RemoteException e){
            addLog("离开游戏失败：" + e.getLocalizedMessage());
            e.printStackTrace();
        }

        playerId = -1;

        return errorCode;
    }

    @Override
    public int joinGame(String playerName){
        if(gameService == null){
            addLog("还未连接，或者连接已经断开，请重新连接。");
            return -1;
        }

        if(playerId >0){
            addLog("已经加入游戏，不用重复加入，pid: " + playerId);
            return this.playerId;
        }

        try{
            playerId = gameService.joinGame(playerName);
            addLog("加入游戏，获得pid：" + playerId);
        }catch (RemoteException e){
            addLog("加入游戏失败：" + e.getLocalizedMessage());
            e.printStackTrace();
            return -1;
        }

        return playerId;
    }

    @Override
    public int playWithAI(int pid) throws RemoteException {
        if(gameService == null){
            return -1;
        }

        return gameService.playWithAI(pid);
    }

    public int playWithAI(){
        int errorCode = GameCode.ERROR;
        try{
            errorCode = playWithAI(playerId);
            addLog("与AI游戏：" + errorCode);
        }catch (RemoteException e){
            addLog("与AI游戏失败：" + e.getLocalizedMessage());
            e.printStackTrace();
        }

        return errorCode;
    }

    @Override
    public int[] getPlayers(int pid) throws RemoteException {
        if(gameService == null){
            return null;
        }

        return gameService.getPlayers(pid);
    }

    public int[] getPlayers(){
        try{
            int[] result = getPlayers(playerId);
            addLog("获取玩家列表, 当前玩家数：" + (result==null?"空":result.length));
            return result;
        }catch (RemoteException e){
            addLog("获取玩家列表失败：" + e.getLocalizedMessage());
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public IRemoteObject asObject() {
        return null;
    }
}
